package com.weibei.common.utils;

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;

/**
 * @Auther: lk
 * @Date: 2018/6/25 14:56
 * @Description:
 */
public class DateUtil {
    public static final String LONG_MODEL = "yyyy-MM-dd HH:mm:ss";
    public static final String LONG3_MODEL = "yyMMddHHmmss";
    public static final String LONG2_MODEL = "yyyy-MM-dd HH:mm";
    public static final String SHORT_MODEL = "yyyy-MM-dd";
    public static final String TIME_MODEL = "hh:mm:ss";
    public static final String TIME_MODEL2 = "hh:mm:ss:SSS";
    public static final String YEAR_MODEL = "yyyy";
    public static final String DATE_MODEL = "yyyyMMdd";
    public static final String DATE_MODEL_2 = "yyyy/MM/dd";
    public static final String DATEMONTH_MODEL = "yyyyMM";
    public static final String DATEMONTH_MODEL_1 = "yyyy-MM";
    public static final String START_TIME = "00:00:00";
    public static final String END_TIME="23:59:59";
    /**
     * 一小时毫秒
     */
    public static final Long HOUR_MILLIS = 1000L * 60 * 60;
    /**
     * 一天毫秒
     */
    public static final Long DAY_MILLIS = HOUR_MILLIS * 24;

    /**
     * 30分钟毫秒
     */
    public static final Long THIRTY_MINUTES_MILLIS = 1000L * 60 * 30;

    public static Date addDay(Date date, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, day);
        return calendar.getTime();
    }

    public static Date addMonth(Date date, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, month);
        return calendar.getTime();
    }

    public static Date addYear(Date date, int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, year);
        return calendar.getTime();
    }

    /**
     * 时间加6个小时
     *
     * @param date
     * @param hour
     * @return
     */

    public static Date addYHour(Date date, int hour) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR, hour);
        return calendar.getTime();
    }

    public static Date addSecond(Date date, int second) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.SECOND, second);
        return calendar.getTime();
    }

    /**
     * 计算 h个小时后的时间 "以fromdate为基准"
     *
     * @param fromdate
     * @param h
     * @return
     */
    public static Date calculateDate(Date fromdate, int h) {

        return calculateDate(fromdate, h, 0);
    }

    /**
     * 计算 h个小时，m分钟后的时间 "以fromdate为基准"
     *
     * @param fromdate
     * @param h
     * @param m
     * @return
     */
    public static Date calculateDate(Date fromdate, int h, int m) {

        Date date = null;
        Calendar cal = Calendar.getInstance();
        cal.setTime(fromdate);
        cal.add(Calendar.HOUR_OF_DAY, h);
        cal.add(Calendar.MINUTE, m);
        date = cal.getTime();
        return date;
    }

    /**
     * 计算 h个小时后的时间 "以当前时间为基准"
     *
     * @param h
     * @return
     */
    public static Date calculateDate(int h) {

        return calculateDate(new Date(), h, 0);
    }

    /**
     * 计算 h个小时，m分钟后的时间 "以当前时间为基准"
     *
     * @param h
     * @param m
     * @return
     */
    public static Date calculateDate(int h, int m) {

        return calculateDate(new Date(), h, m);
    }

    public static Date currentDate() {
        return new Date();
    }

    public static Date currentDate(String format) {
        String d = dateFormat(currentDate(), format);
        return StringToDate(d, format);
    }

    public static Long currentTimeMillis() {
        return System.currentTimeMillis();
    }

    /**
     * 时间大小的比较，返回相差的毫秒数
     *
     * @param d1
     * @param d2
     * @return
     */
    public static long dateCompare(Date d1, Date d2) {
        Calendar cal = Calendar.getInstance();
        Calendar ca2 = Calendar.getInstance();
        cal.setTime(d1);
        ca2.setTime(d2);
        long l1 = cal.getTimeInMillis();
        long l2 = ca2.getTimeInMillis();
        return l1 - l2;
    }

    /**
     * 两个时间相差的分钟数
     *
     * @param d1
     * @param d2
     * @return
     */
    public static long dateDiff(Date d1, Date d2) {

        return dateCompare(d1, d2) / 1000 / 60;
    }

    /**
     * 时间格式化
     *
     * @param d
     * @return
     */
    public static String dateFormat(Date d) {
        SimpleDateFormat sdf = new SimpleDateFormat(LONG_MODEL);
        return sdf.format(d);
    }

    public static String dateFormatModel(Date d) {
        SimpleDateFormat sdf = new SimpleDateFormat(DATE_MODEL);
        return sdf.format(new Date());
    }

    /**
     * 时间格式化
     *
     * @param d
     * @return
     */
    public static String dateFormat(Date d, String model) {
        if (d == null) {
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(model);
        return sdf.format(d);
    }
    /*	*//**
     * 判断日期 格式化后是否相同
     *
     * @param d
     * @param d2
     * @return
     *//*
     * public templates Boolean equals(Date d,Date d2,String model){ SimpleDateFormat
     * sdf=new SimpleDateFormat(model); return StringUtils.equals(sdf.format(d),
     * sdf.format(d2)); }
     */

    /**
     * 时间格式化
     *
     * @param d
     * @return
     */
    public static String dateFormatforYear(Date d) {
        SimpleDateFormat sdf = new SimpleDateFormat(YEAR_MODEL);
        return sdf.format(d);
    }

    /**
     * 年月日格式化
     *
     * @param d
     * @return
     */
    public static String dateFormatForymd(Date d) {
        SimpleDateFormat sdf = new SimpleDateFormat(SHORT_MODEL);
        return sdf.format(d);
    }

    public static String dateFormatShort(Date d) {
        SimpleDateFormat sdf = new SimpleDateFormat(LONG3_MODEL);
        return sdf.format(d);
    }

    public static Date dateTimeNow() {
        return new Date(System.currentTimeMillis());
    }

    /**
     * 两个时间相差的天数
     *
     * @param d1
     * @param d2
     * @return
     */
    public static int diffDays(Date d1, Date d2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(d1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(d2);
        int day1 = cal1.get(Calendar.DAY_OF_YEAR);
        int day2 = cal2.get(Calendar.DAY_OF_YEAR);

        int year1 = cal1.get(Calendar.YEAR);
        int year2 = cal2.get(Calendar.YEAR);
        if (year1 != year2) // 同一年
        {
            int timeDistance = 0;
            for (int i = year1; i < year2; i++) {
                if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) // 闰年
                {
                    timeDistance += 366;
                } else // 不是闰年
                {
                    timeDistance += 365;
                }
            }

            return timeDistance + (day2 - day1);
        } else // 不同年
        {
            System.out.println("判断day2 - day1 : " + (day2 - day1));
            return day2 - day1;
        }
    }

    /**
     * 本月第一天
     *
     * @param date
     * @return
     */
    public static Date firstDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public static String getMaxDate(String dates, String dateFormat) {
        String[] strs = dates.split(",");
        String result = "";
        Date d;
        Date max = null;
        for (int i = 0; i < strs.length; i++) {
            d = StringToDate(strs[i], dateFormat);
            if (d == null) {
                continue;
            }
            if (max == null || max.getTime() < d.getTime()) {
                max = d;
            }
        }
        if (max != null) {
            result = dateFormat(max, dateFormat);
        }
        return result;
    }

    // 往后加一天
    public static String getSpecifiedDayAfter(String specifiedDay) {
        Calendar c = Calendar.getInstance();
        Date date = null;
        try {
            date = new SimpleDateFormat("yy-MM-dd").parse(specifiedDay);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        c.setTime(date);
        int day = c.get(Calendar.DATE);
        c.set(Calendar.DATE, day + 1);
        String dayAfter = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
        return dayAfter;
    }


    public static Date nextDay(Date date) {
        return addDay(date, 1);
    }

    /**
     * 获取下个月第一天
     *
     * @param date
     * @return
     */
    public static Date nextMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 字符串转日期，支持两种格式 1."日期 时间" 2."纯日期"
     *
     * @param s
     * @return
     * @throws ParseException
     */
    public static Date StringToDate(String s) {

        DateFormat sdf = new SimpleDateFormat(LONG_MODEL);
        try {
            return sdf.parse(s);
        } catch (ParseException e) {
            DateFormat sdf2 = new SimpleDateFormat(SHORT_MODEL);
            try {
                return sdf2.parse(s);
            } catch (ParseException e2) {
            }
        }
        return null;
    }

    public static Date StringToDate(String s, String format) {
        if (s.length() > 0) {
            try {
                DateFormat sdf = new SimpleDateFormat(format);
                return sdf.parse(s);
            } catch (ParseException e) {
            }
        }
        return null;
    }

    public static Date formatDateTime(Date date, String format) {
        DateFormat dateFormat = new SimpleDateFormat(format);
        String dateStr = dateFormat.format(date);
        try {
            return dateFormat.parse(dateStr);
        } catch (ParseException ignored) {
        }
        return null;
    }

    /**
     * 转换成天
     *
     * @param millis
     * @return
     */
    public static Integer toDay(Long millis) {
        return Long.valueOf(millis / DAY_MILLIS).intValue();
    }

    /**
     * 毫秒转换小时
     *
     * @param millis
     * @return
     */
    public static Integer toHour(Long millis) {
        return Long.valueOf(millis / HOUR_MILLIS).intValue();
    }

    public static Integer upYear(Date date) {
        Calendar calendar = Calendar.getInstance();
        if (date != null) {
            calendar.setTime(date);
        } else {
            calendar.setTime(new Date());
        }
        return calendar.get(Calendar.YEAR) - 1;
    }

    public static Date setHourForDate(Date date, int hour) throws Exception {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public static Date localDateTime2Date(LocalDateTime localDateTime) {
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zdt = localDateTime.atZone(zoneId);//Combines this date-time with a time-zone to create a  ZonedDateTime.
        Date date = Date.from(zdt.toInstant());
        return date;
    }

    // 获得某天最大时间23:59:59
    public static Date getEndOfDay(Date date) {
        Calendar calendarEnd = Calendar.getInstance();
        calendarEnd.setTime(date);
        calendarEnd.set(Calendar.HOUR_OF_DAY, 23);
        calendarEnd.set(Calendar.MINUTE, 59);
        calendarEnd.set(Calendar.SECOND, 59);
        //防止mysql自动加一秒,毫秒设为0
        calendarEnd.set(Calendar.MILLISECOND, 0);
        return calendarEnd.getTime();
    }

    // 获得某天最小时间00:00:00
    public static Date getStartOfDay(Date date) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
        LocalDateTime startOfDay = localDateTime.with(LocalTime.MIN);
        return Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获取10位时间戳
     *
     * @param dateStr
     * @return
     */
    public static long getTimestamp(String dateStr) {
        Date date = DateUtil.StringToDate(dateStr, "yyyy-MM-dd HH:mm:ss");
        Long timestamp = date.getTime();
        //获取10位时间戳，除以1000
        timestamp = timestamp / 1000;
        return timestamp;
    }

    /**
     * 获取13位时间戳
     *
     * @param dateStr
     * @return
     */
    public static long getLongTimestamp(String dateStr) {
        Date date = DateUtil.StringToDate(dateStr, "yyyy-MM-dd HH:mm:ss");
        Long timestamp = date.getTime();
        return timestamp;
    }

    /**
     * 获取10位时间戳
     *
     * @param date
     * @return
     */
    public static long getTimestamp(Date date) {
        Long timestamp = date.getTime();
        //获取10位时间戳，除以1000
        timestamp = timestamp / 1000;
        return timestamp;
    }

    /**
     * 将10 or 13 位时间戳转为时间字符串
     * convert the number 1407449951 1407499055617 to date/time format timestamp
     */
    public static Date timestamp2Date(String str_num) {
        SimpleDateFormat sdf = new SimpleDateFormat(LONG_MODEL);
        if (str_num.length() == 13) {
            return new Date(Long.valueOf(str_num));
        } else {
            return new Date(Integer.valueOf(str_num) * 1000L);
        }
    }

    public static String getFromatterDateStr(Date date) {
        // 拿到当前时间戳和发布时的时间戳，然后得出时间戳差
        Date curTime = new Date();
        long timeDiff = curTime.getTime() - date.getTime();
        //上面一行代码可以换成以下（兼容性的解决）

        // 单位换算
        long min = 60 * 1000;
        long hour = min * 60;
        long day = hour * 24;
        long week = day * 7;
        long month = week * 4;
        long year = month * 12;
        DecimalFormat df = new DecimalFormat("#");
        // 计算发布时间距离当前时间的周、天、时、分
        double exceedyear = Math.floor(timeDiff / year);
        double exceedmonth = Math.floor(timeDiff / month);
        double exceedWeek = Math.floor(timeDiff / week);
        double exceedDay = Math.floor(timeDiff / day);
        double exceedHour = Math.floor(timeDiff / hour);
        double exceedMin = Math.floor(timeDiff / min);


        // 最后判断时间差到底是属于哪个区间，然后return

        if (exceedyear < 100 && exceedyear > 0) {
            return "0".equals(df.format(exceedyear)) ? "刚刚" : df.format(exceedyear) + "年前";
        } else {
            if (exceedmonth < 12 && exceedmonth > 0) {
                return "0".equals(df.format(exceedmonth)) ? "刚刚" : df.format(exceedmonth) + "月前";
            } else {
                if (exceedWeek < 4 && exceedWeek > 0) {
                    return "0".equals(df.format(exceedWeek)) ? "刚刚" : df.format(exceedWeek) + "星期前";
                } else {
                    if (exceedDay < 7 && exceedDay > 0) {
                        return "0".equals(df.format(exceedDay)) ? "刚刚" : df.format(exceedDay) + "天前";
                    } else {
                        if (exceedHour < 24 && exceedHour > 0) {
                            return "0".equals(df.format(exceedHour)) ? "刚刚" : df.format(exceedHour) + "小时前";
                        } else {
                            df.format(exceedMin);
                            return "0".equals(df.format(exceedMin)) ? "刚刚" : df.format(exceedMin) + "分钟前";
                        }
                    }
                }
            }
        }
    }

    /** * 获取当前月份第一天的日期 *
     * @return 格式化后的日期
     */
    public static String getFirstDayOfThisMonth() {
        SimpleDateFormat myFormatter = new SimpleDateFormat(SHORT_MODEL);
        Calendar cal = Calendar.getInstance();    cal.set(Calendar.DAY_OF_MONTH, 1);
        return myFormatter.format(cal.getTime());
    }

    /** * 获取当前月份最后一天 * @return 格式化的日期 */
    public static String getMaxDayOfThisMonth() {
        SimpleDateFormat myFormatter = new SimpleDateFormat(SHORT_MODEL);
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DATE, 1);
        //主要就是这个roll方法
        cal.roll(Calendar.DATE, -1);
        return myFormatter.format(cal.getTime());
    }

    /** * 获取某月份最后一天 * @return 格式化的日期 */
    public static String getMaxDayOfMonth(Date d) {
        SimpleDateFormat myFormatter = new SimpleDateFormat(SHORT_MODEL);
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);
        cal.set(Calendar.DATE, 1);
        //主要就是这个roll方法
        cal.roll(Calendar.DATE, -1);
        return myFormatter.format(cal.getTime());
    }

    /**
     * 将毫秒格式化成时间（天，时，分，秒）
     * @param mSeconds
     * @return
     */
    public static String formatMsToTime(long mSeconds) {
        StringBuffer sb = new StringBuffer();
        long day = 0;
        long hour = 0;
        long minute = 0;
        long second = 0;
        long msercond = 0;
        boolean dayNotAlready = false;
        boolean hourNotAlready = false;
        boolean minuteNotAlready = false;
        boolean secondNotAlready = false;

        if (mSeconds > 0) {
            if (mSeconds > 1000) {
                secondNotAlready = true;
                second = mSeconds / 1000;
                msercond = mSeconds % 1000;
                if (second >= 60) {
                    minuteNotAlready = true;
                    minute = second / 60;
                    second = second % 60;
                    if (minute >= 60) {
                        hourNotAlready = true;
                        hour = minute / 60;
                        minute = minute % 60;
                        if (hour > 24) {
                            dayNotAlready = true;
                            day = hour / 24;
                            hour = hour % 24;
                        }
                    }
                }
            }
        }
        if (day > 0){
            sb.append(day + "天");
        }
        if (hour > 0){
            sb.append(hour + "小时");
        }
        if (minute > 0){
            sb.append(minute + "分钟");
        }
        if (second > 0){
            sb.append(second + "秒");
        }
        if (msercond > 0){
            sb.append(msercond + "毫秒");
        }
        return sb.toString();
    }

    /**
     * 获取时间差
     * @param largeDay yyyy-MM-dd
     * @param smallDay yyyy-MM-dd
     * @return
     */
    public static int distanceDay(Date largeDay, Date smallDay) {
        int day = (int) ((largeDay.getTime() - smallDay.getTime()) / (1000 * 60 * 60 * 24));
        return day;
    }

    /**
     *功能描述 组装日期和时间为日期
     * @author daixilong
     * @date 2021/5/8
     * @param date
     * @param time
     * @return java.lang.String
     */
    public static String formatDate(String date,String time){
        return   LocalDateTime.of(LocalDate.parse(date),LocalTime.parse(time)).format(DateTimeFormatter.ofPattern(LONG_MODEL));
    }
}
